package com.biostime.springdraw.common.persistence;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.biostime.springdraw.common.utils.StringUtils;

/**
 * 树形列表
 * @author phil
 * @version 2015-11-08
 */
public class TreeList<T extends TreeEntity<T>> {
	
	private Map<String,TreeNode> treeMaps = new HashMap<String,TreeNode>();
	private String icon;
	
	public TreeList(List<T> orgins,String icon){
		this.icon = icon;
		
		String name = "";
		for(T node : orgins){
			if(!StringUtils.isEmpty(icon)){
				name = node.getName();
				
				//name = "├ "+name;
				name = this.icon + name;
				name = StringUtils.stringOfChar(node.getLayer()-1, "　") + name;
				node.setName(name);
			}
			treeMaps.put(node.getId(), new TreeNode(node));
		}
		
		for(Map.Entry<String, TreeNode> node : treeMaps.entrySet()){
			T data = node.getValue().getNode();
			TreeNode parent = treeMaps.get(data.getParent().getId());
			if(parent!=null){
				parent.getChilds().add(node.getValue());
				node.getValue().setParent(parent);
			}
		}
	}
	
	public List<T> toList(){
		List<T> rets = new ArrayList<T>();
		for(Map.Entry<String, TreeNode> node : treeMaps.entrySet()){
			TreeNode treeNode = node.getValue();
			if(treeNode.isRoot()){
				toList(rets,treeNode);
			}
		}
		return rets;
	}
	
	private void toList(List<T> rets,TreeNode node){
		rets.add(node.getNode());
		
		Collections.sort(node.getChilds(),new Comparator<TreeNode>(){

			@Override
			public int compare(TreeNode o1, TreeNode o2) {
				return o1.getNode().getSort()-o2.getNode().getSort();
			}
			
		});
		
		for(TreeNode child : node.getChilds()){
			toList(rets,child);
		}
	}
	
	public class TreeNode {
		private T node;
		private TreeNode parent;
		private List<TreeNode> childs = new ArrayList<TreeNode>();
		
		public TreeNode(T node){
			this.node = node;
		}
		
		public T getNode() {
			return node;
		}

		public void setNode(T node) {
			this.node = node;
		}

		public boolean isRoot(){
			return getParent() == null;
		}

		public TreeNode getParent() {
			return parent;
		}

		public void setParent(TreeNode parent) {
			this.parent = parent;
		}

		public List<TreeNode> getChilds() {
			return childs;
		}

		public void setChilds(List<TreeNode> childs) {
			this.childs = childs;
		}
	}
}
